# -*- coding: utf-8 -*-
"""
Created on Thu Jun 16 14:03:11 2022

@author: tregan
"""

import pandas as pd
import numpy as np
import time


machine="C:/Users/tanne/Dropbox/My PC (LAPTOP-V4OB9LQR)/Desktop/LeveragingInformalInstitutions/REStat/Accepted/data_replication/"

cdir=machine+"/code/"

exch=2288 #exchange rate, TZS per USD
df=pd.read_csv(cdir+"temp/appended_WTP_early_payers_leaders.csv")
df=df[df.WTP.isnull()==0]

ep=df['early_payer'].to_numpy()
plot_size=df['lot_area_inv'].to_numpy()
pop_weight=df['weight'].to_numpy()
wtp=df['WTP'].to_numpy()/exch #update to USD
wtp_ldr=df['WTP_all'].to_numpy()/exch #update to USD



#functions---------------------------------------------------------------------
def tru_rev(params,w=wtp,s=plot_size,wt=pop_weight):
    p=params[0]+params[1]*s+params[2]*(s>=300)+params[3]*(s>800)+params[4]*(s>2500)
    q=(w>=p)*wt
    #return revenue
    return sum(p*q)/sum(wt)

def tru_upt(params,w=wtp,s=plot_size,wt=pop_weight):
    p=params[0]+params[1]*s+params[2]*(s>=300)+params[3]*(s>800)+params[4]*(s>2500)
    q=(w>=p)*wt
    #return uptake
    return sum(q)/sum(wt)

def tru_pgs(params,w=wtp,s=plot_size,wt=pop_weight):
    p=params[0]+params[1]*s+params[2]*(s>=300)+params[3]*(s>800)+params[4]*(s>2500)
    pg=(w-p)*(w>=p)*wt
    #return private gains
    return sum(pg)/sum(wt)

def ldr_rev(params,w=wtp_ldr,s=plot_size,wt=pop_weight):
    p=params[0]+params[1]*s+params[2]*(s>=300)+params[3]*(s>800)+params[4]*(s>2500)
    q=(w>=p)*wt
    #return revenue
    return sum(p*q)/sum(wt)

def ldr_upt(params,w=wtp_ldr,s=plot_size,wt=pop_weight):
    p=params[0]+params[1]*s+params[2]*(s>=300)+params[3]*(s>800)+params[4]*(s>2500)
    q=(w>=p)*wt
    #return uptake
    return sum(q)/sum(wt)


def revenue_1st():
    wt=pop_weight
    q=(wtp>wtp_ldr)*wt
    return sum(wtp_ldr*q)/sum(wt)
def uptake_1st():
    wt=pop_weight
    q=(wtp>wtp_ldr)*wt
    return sum(q)/sum(wt)
def private_gains_1st():
    wt=pop_weight
    pg=(wtp-wtp_ldr)*(wtp>=wtp_ldr)*wt
    return sum(pg)/sum(wt)
def revenue_1st_prf():
    wt=pop_weight
    q=(wtp>=wtp)*wt
    return sum(wtp*q)/sum(wt)



#SCRIPT========================================================================
#row 1: baseline revenue-------------------------------------------------------
s=plot_size
p=127+0.18*s+27*(s>=300)+27*(s>800)+27*(s>2500)
wt=pop_weight
q=ep*wt
rv,up,pgs=sum(p*q)/sum(wt), sum(q)/sum(wt), sum((wtp-p)*q)/sum(wt)

#output
row1=[127,0.18,27,round(rv), round(up,2) ,0,'']
revenue_constraint=rv



#row 2: uniform revenue max----------------------------------------------------
a_lst=[x for x in range(-10,130)]
b_lst=[0]
d_lst=[0]
params=[(a,b,d,d,d) for a in a_lst for b in b_lst for d in d_lst]

#leader info 
r_lst=[ldr_rev(x) for x in params]
param_star=params[r_lst.index(max(r_lst))]

rev_ldr=tru_rev(param_star)
upt_ldr=tru_upt(param_star)
pgs_ldr=tru_pgs(param_star)

#perfect info
r_lst=[tru_rev(x) for x in params]
rev_prf=r_lst[r_lst.index(max(r_lst))]

#output
row2=[round(param_star[0]), '.', '.',
      round(rev_ldr), round(upt_ldr,2),round(pgs_ldr), round(rev_prf)]



#row 3: 3rd degree revenue max-------------------------------------------------
a_lst=[x for x in range(-10,130)]
b_lst=[x/100 for x in range(0,50)]
d_lst=[x for x in range(-10,40)]
print(len(a_lst)*len(b_lst)*len(d_lst))
params=[(a,b,d,d,d) for a in a_lst for b in b_lst for d in d_lst]

#leader info 
start = time.time()
r_lst=[ldr_rev(x) for x in params]
param_star=params[r_lst.index(max(r_lst))]
print("time to get leader params: {}s".format(round(time.time() - start)))
rev_ldr=tru_rev(param_star)
upt_ldr=tru_upt(param_star)
pgs_ldr=tru_pgs(param_star)

#perfect info
start = time.time()
rev_prf=max(map(tru_rev,params))
print("time to get true params: {}s".format(round(time.time() - start)))

#output
row3=[round(param_star[0]), round(param_star[1],2), round(param_star[2]),
      round(rev_ldr), round(upt_ldr,2),round(pgs_ldr), round(rev_prf)]



#row 4: flexible deltas revenue max--------------------------------------------
#NB: here i reduce the range of each parameter to keep dimensionality down
a_lst=[x*2 for x in range(-5,90)]
b_lst=[x/100 for x in range(0,20)]
d_lst=[x*2 for x in range(-5,10)]
d2_lst=[x*2 for x in range(-5,10)]
d3_lst=[x*2 for x in range(-5,10)]
print(len(a_lst)*len(b_lst)*len(d_lst)*len(d2_lst)*len(d3_lst))
params=[(a,b,d,d2,d3) for a in a_lst for b in b_lst for d in d_lst for d2 in d2_lst for d3 in d3_lst]

#leader info 
start = time.time()
r_lst=[ldr_rev(x) for x in params]
param_star=params[r_lst.index(max(r_lst))]
print("time to get leader params: {}s".format(round(time.time() - start)))
rev_ldr=tru_rev(param_star)
upt_ldr=tru_upt(param_star)
pgs_ldr=tru_pgs(param_star)

#perfect info
start = time.time()
rev_prf=max(map(tru_rev,params))
print("time to get true params: {}s".format(round(time.time() - start)))

#output
row4=['.', '.', '.',
      round(rev_ldr), round(upt_ldr,2),round(pgs_ldr), round(rev_prf)]




#row 5: 1st degree revenue max-------------------------------------------------
#leader info 
rev_ldr=revenue_1st()
upt_ldr=uptake_1st()
pgs_ldr=private_gains_1st()
#perfect info
rev_prf=revenue_1st_prf()

#output
row5=['.', '.', '.',
      round(rev_ldr), round(upt_ldr,2),round(pgs_ldr), round(rev_prf)]


#row 6: uniform uptake max (125% revenue target)----------------------------
a_lst=[x for x in range(-10,130)]
b_lst=[0]
d_lst=[0]
params=[(a,b,d,d,d) for a in a_lst for b in b_lst for d in d_lst]

#leader info 
u_lst=[ldr_upt(x)*(ldr_rev(x)>=revenue_constraint*1.25) for x in params]
param_star=params[u_lst.index(max(u_lst))]
rev_ldr=tru_rev(param_star)
upt_ldr=tru_upt(param_star)
pgs_ldr=tru_pgs(param_star)

#perfect info
u_lst=[tru_upt(x)*(tru_rev(x)>=revenue_constraint*1.25) for x in params]
upt_prf=u_lst[u_lst.index(max(u_lst))]


#output
row6=[round(param_star[0]), '.', '.',
      round(rev_ldr), round(upt_ldr,2),round(pgs_ldr), round(upt_prf,2)]

#row 7: 3rd degree uptake max (125% revenue target)----------------------------
a_lst=[x for x in range(-10,130)]
b_lst=[x/100 for x in range(0,50)]
d_lst=[x for x in range(-10,40)]
params=[(a,b,d,d,d) for a in a_lst for b in b_lst for d in d_lst]

#leader info 
start = time.time()
u_lst=[ldr_upt(x)*(ldr_rev(x)>=revenue_constraint*1.25) for x in params]
param_star=params[u_lst.index(max(u_lst))]
print("time to get leader params: {}s".format(round(time.time() - start)))
rev_ldr=tru_rev(param_star)
upt_ldr=tru_upt(param_star)
pgs_ldr=tru_pgs(param_star)

#perfect info
start = time.time()
u_lst=[tru_upt(x)*(tru_rev(x)>=revenue_constraint*1.25) for x in params]
upt_prf=u_lst[u_lst.index(max(u_lst))]
print("time to get true params: {}s".format(round(time.time() - start)))

#output
row7=[round(param_star[0]), round(param_star[1],2), round(param_star[2]),
      round(rev_ldr), round(upt_ldr,2),round(pgs_ldr), round(upt_prf,2)]


#row 8: 3rd degree uptake max (125% revenue target)----------------------------
#NB: here i reduce the range of each parameter to keep dimensionality down
a_lst=[x*2 for x in range(-5,90)]
b_lst=[x/100 for x in range(0,20)]
d_lst=[x*2 for x in range(-5,10)]
d2_lst=[x*2 for x in range(-5,10)]
d3_lst=[x*2 for x in range(-5,10)]
print(len(a_lst)*len(b_lst)*len(d_lst)*len(d2_lst)*len(d3_lst))
params=[(a,b,d,d2,d3) for a in a_lst for b in b_lst for d in d_lst for d2 in d2_lst for d3 in d3_lst]

#leader info 
start = time.time()
u_lst=[ldr_upt(x)*(ldr_rev(x)>=revenue_constraint*1.25) for x in params]
param_star=params[u_lst.index(max(u_lst))]
print("time to get leader params: {}s".format(round(time.time() - start)))
rev_ldr=tru_rev(param_star)
upt_ldr=tru_upt(param_star)
pgs_ldr=tru_pgs(param_star)

#perfect info
start = time.time()
u_lst=[tru_upt(x)*(tru_rev(x)>=revenue_constraint*1.25) for x in params]
upt_prf=u_lst[u_lst.index(max(u_lst))]
print("time to get true params: {}s".format(round(time.time() - start)))

#output
row8=['.', '.', '.',
      round(rev_ldr), round(upt_ldr,2),round(pgs_ldr), round(upt_prf,2)]



#create table------------------------------------------------------------------
table=[]
for r in [row1,row2,row3,row4,row5,row6,row7, row8]:
    table.append(r)
table
